package com.dr.cmdb.core.aop;


import com.dr.cmdb.common.model.errorcode.BaseCode;
import com.dr.cmdb.core.config.CustomizeConfig;
import com.dr.cmdb.core.dto.FiledCheckDto;
import com.dr.cmdb.core.annotation.ModelCheck;
import com.dr.cmdb.core.dto.ModelPropertyDto;
import com.dr.cmdb.core.dto.TableModelsDto;
import com.dr.cmdb.core.exception.BizException;
import com.dr.cmdb.core.filedcheck.FiledCheckHandlerFactory;
import com.dr.cmdb.core.service.ModelService;
import com.dr.cmdb.core.service.TablesService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author rui.duan
 * @version 1.0
 * @className ModelCheckAspect
 * @description 模型字段校验
 * @date 2019-06-10 19:23
 */
@Aspect
@Component
public class ModelCheckAspect {


    @Autowired
    private ModelService modelService;

    @Autowired
    private CustomizeConfig customizeConfig;

    @Pointcut("@annotation(com.dr.cmdb.core.annotation.ModelCheck)")
    public void modelCheckAspect() {
    }

    @Before("modelCheckAspect()")
    public void doBefore(JoinPoint joinPoint) {
        //拿到被注解的方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //拿到被注解的方法
        Method method = signature.getMethod();
        Method targetMethod = AopUtils.getMostSpecificMethod(method, joinPoint.getTarget().getClass());
        //拿到注解类的参数
        Object[] arguments = joinPoint.getArgs();
        if (null == arguments || arguments.length <= 0) {
            throw new BizException(BaseCode.PARAM_ERROR);
        }
        ModelCheck modelCheck = AnnotationUtils.findAnnotation(targetMethod, ModelCheck.class);
        //先匹配方法名
        Map<String, Object> argument = (Map<String, Object>) arguments[0];
        List<ModelPropertyDto> modelProperties = modelService.getModelProperties((String) argument.get(customizeConfig.getCiTableName()));
        if (CollectionUtils.isEmpty(modelProperties)) {
            throw new BizException(BaseCode.PARAM_ERROR);
        }
        FiledCheckDto build = FiledCheckDto.builder()
                .argument(argument)
                .tableCols(modelProperties)
                .checkEnums(Arrays.asList(modelCheck.value()))
                .ciTableName(customizeConfig.getCiTableName())
                .build();
        FiledCheckHandlerFactory.processHandler(build);
    }


}
